/*
 * This file is part of aion-unique <aion-unique.org>.
 *
 *  aion-unique is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  aion-unique is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with aion-unique.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.aionengine.gameserver.skillengine.properties;

import com.aionengine.gameserver.model.gameobjects.Creature;
import com.aionengine.gameserver.model.gameobjects.player.Player;
import com.aionengine.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE;
import com.aionengine.gameserver.skillengine.model.Skill;
import com.aionengine.gameserver.skillengine.properties.Properties.CastState;
import com.aionengine.gameserver.utils.MathUtil;
import com.aionengine.gameserver.utils.PacketSendUtility;
import com.aionengine.gameserver.world.geo.GeoService;

/**
 * @author ATracer
 */
public class FirstTargetRangeProperty {

    /**
     * @param skill
     * @param properties
     */
    public static boolean set(Skill skill, Properties properties, CastState castState) {
        float firstTargetRange = properties.getFirstTargetRange();
        if (!skill.isFirstTargetRangeCheck())
            return true;

        Creature effector = skill.getEffector();
        Creature firstTarget = skill.getFirstTarget();

        if (firstTarget == null)
            return false;

        // Add Weapon Range to distance
        if (properties.isAddWeaponRange()) {
            firstTargetRange += (float) skill.getEffector().getGameStats().getAttackRange().getCurrent() / 1000f;
        }

        //on end cast check add revision distance value
        if (!castState.isCastStart())
            firstTargetRange += properties.getRevisionDistance();

        if (firstTarget.getObjectId() == effector.getObjectId()) {
            return true;
        }

        if (!MathUtil.isInAttackRange(effector, firstTarget, firstTargetRange + 2)) {
            if (effector instanceof Player) {
                PacketSendUtility.sendPacket((Player) effector, SM_SYSTEM_MESSAGE.STR_ATTACK_TOO_FAR_FROM_TARGET);
            }
            return false;
        }

        // TODO check for all targets too
        // Summon Group Member exception
        if (skill.getSkillTemplate().getSkillId() != 1606) {
            if (!GeoService.getInstance().canSee(effector, firstTarget)) {
                if (effector instanceof Player) {
                    PacketSendUtility.sendPacket((Player) effector, SM_SYSTEM_MESSAGE.STR_SKILL_OBSTACLE);
                }
                return false;
            }
        }
        return true;
    }

}
